<?php
/**
 * Created by PhpStorm.
 * User: dong
 * Date: 2018/5/14
 * Time: 20:49
 */
namespace App\Services\ThirdPayments\Recharge;

use App\Exceptions\RechargeGatewayException;
use App\Lib\Code;
use App\Lib\PaymentMap;
use App\Lib\ThirdPartyMap;
use App\Models\IndexOrderno;
use App\Models\RechargeOrder;
use App\Services\ThirdPayments\BankTraits\HFTBankMap;
use App\Services\ThirdPayments\Contracts\Actions\HrefRedirectAction;
use App\Services\ThirdPayments\Contracts\Actions\QrCodeAction;
use App\Services\ThirdPayments\Contracts\QRCapable;
use App\Services\ThirdPayments\Contracts\RechargeBaseAbstract;
use App\Services\ThirdPayments\Contracts\WAPable;
use Illuminate\Support\Facades\Log;

class HFTXPayment extends RechargeBaseAbstract implements QRCapable, WAPable
{
    use HFTBankMap;

    protected $gw_pay = 'http://180.97.188.210:52/pay';
//    protected $gw_pay = 'http://hengfu.guangzhoucaimao.cn/pay';
    protected $gw_query = 'https://hf.paygetway.top/Pay/';
//    protected $gw_query = 'http://hengfu.guangzhoucaimao.cn/pay';
    public function callback(array $data)
    {
        // TODO: Implement callback() method.
        if ($this->veryCallbackSign($data)) {
            if ($data['fxstatus'] == 1) {
                return true;
            }
        }
        return false;
    }

    public function veryCallbackSign(array $data)
    {
        // TODO: Implement veryCallbackSign() method.
        $signStr = "";
        $signStr .= $data['fxstatus'];
        $signStr .= $data['fxid'];
        $signStr .= $data['fxddh'];
        $signStr .= $data['fxfee'];
        $signStr .= $this->getMchKey();
        if (strcasecmp($data['fxsign'], md5($signStr)) == 0) return true;
        return false;
    }

    public function getOrderNoFromCallback(array $data)
    {
        // TODO: Implement getOrderNoFromCallback() method.
        return $data['fxddh'];
    }

    public function getOrderAmtFromCallback(array $data)
    {
        // TODO: Implement getOrderAmtFromCallback() method.
        return $data['fxfee'];
    }

    public function getThirdNoFromCallback(array $data)
    {
        return $data['fxorder'];
    }

    /**
     * @return mixed
     */
    public function getIdentify(): string
    {
        // TODO: Implement getIdentify() method.
        return ThirdPartyMap::HENGFUTX;
    }

    /**
     *  needs child to achieve
     */
    public function initPaymentMap(): array
    {
        // TODO: Implement initPaymentMap() method.
        return [
            PaymentMap::WX => 'wxsm',
            PaymentMap::QQ => 'qqsm',
            PaymentMap::QQ_WAP => 'qqwap',
            PaymentMap::BANK => 'bank',
            PaymentMap::BANK_WAP => 'ylkj',
            PaymentMap::ALI => 'zfbsm',
            PaymentMap::ALI_WAP => 'zfbwap',
            PaymentMap::JD_WAP => 'jdwap'
        ];
    }

    public function query(RechargeOrder $rechargeOrder)
    {
        // TODO: Implement query() method.
        $this->setParameter('fxid', $this->getMchId());
        $this->setParameter('fxddh', $rechargeOrder->plat_no);
        $this->setParameter('fxaction', 'orderquery');
        $this->setParameter('fxsign', $this->querySign());
        $res = curlHttp($this->getGwQuery(), $this->getParameters());
        if ($res['http_code'] == 200) {
            $body = json_decode($res['body'], true);
            if ($body['fxstatus'] == 1) return true;
            return '支付异常:'. @$body['error'];
        }
        return '查询接口请求失败:' . $res['body'];
    }

    public function bankHref(RechargeOrder $rechargeOrder)
    {
        // TODO: Implement bankHref() method.
        $url = $this->getPostResUrl($rechargeOrder);
        return $url;
    }

    public function scanCode(RechargeOrder $rechargeOrder)
    {
        // TODO: Implement scanCode() method.
        $url = $this->getPostResUrl($rechargeOrder);
        return $url;
    }

    public function paySign(): string
    {
        // TODO: Implement paySign() method.
        $signStr = "";
        $signStr .= $this->getParameter('fxid');
        $signStr .= $this->getParameter('fxddh');
        $signStr .= $this->getParameter('fxfee');
        $signStr .= $this->getParameter('fxnotifyurl');
        $signStr .= $this->getMchKey();
        return md5($signStr);
    }

    public function querySign(): string
    {
        // TODO: Implement querySign() method.
        $signStr = "";
        $signStr .= $this->getParameter('fxid');
        $signStr .= $this->getParameter('fxddh');
        $signStr .= $this->getParameter('fxaction');
        $signStr .= $this->getMchKey();
        return md5($signStr);
    }

    public function showSuccess(): string
    {
        // TODO: Implement showSuccess() method.
        return 'success';
    }

    public function initParameters(RechargeOrder $rechargeOrder)
    {
        // TODO: Implement initParameters() method.
        $mchData = $rechargeOrder->order_data;
        if ($mchData['recharge_type'] == PaymentMap::BANK_WAP) {
            $firstOrderNo = IndexOrderno::orderBy('created_at', 'desc')->first();
            $id = $firstOrderNo->id < 100000
                ? str_pad($firstOrderNo->id, 6, 0, STR_PAD_LEFT)
                : $firstOrderNo->id;
            $rechargeOrder->plat_no = $id . $rechargeOrder->plat_no;
            $rechargeOrder->save();
        }
        if ($mchData['recharge_type'] == PaymentMap::BANK) {
            $attach = $this->getBank($mchData['bank_code']);
        } else {
            $attach = $this->setRemark($rechargeOrder);
        }
        $rechargeOrder->plat_no = str_random(1);
        $rechargeOrder->save();
        $this->setParameter('fxid', $this->getMchId());
        $this->setParameter('fxddh', $rechargeOrder->plat_no);
        $this->setParameter('fxdesc', array_key_exists('body', $mchData)?$mchData['body']: 'order_pay');
        $this->setParameter('fxfee', $rechargeOrder->order_amt);
        $this->setParameter('fxattch', $attach);
        $this->setParameter('fxnotifyurl', $this->getCallbackUrl());
        $this->setParameter('fxbackurl', $this->getReturnUrl($rechargeOrder->plat_no));
        $this->setParameter('fxpay', $this->getPaymentMap($mchData['recharge_type']));
        $this->setParameter('fxsign', $this->paySign());
        $this->setParameter('fxip', request()->getClientIp());
    }

    public function getPostResUrl(RechargeOrder $rechargeOrder)
    {
        $this->initParameters($rechargeOrder);
        $url = $this->getGwPay();
        $params = $this->getParameters();
        $res = curlHttp($url, $params, 'post');
        if ($res['http_code'] == 200) {
            Log::info($res['body']);
            $body = json_decode($res['body'], true);
            if ($body['status'] == 1) {
//                $url = parse_url($body['payurl'], PHP_URL_QUERY);
//                parse_str($url, $output);
//                return $output['url'];
                return $body['payurl'];
            }
            throw new RechargeGatewayException($this, $res['body'], '接口校验失败：'.$body['error'], Code::RECHARGE_THIRD_LOG);
        }
        throw new RechargeGatewayException($this, $res['body'], '接口请求失败', Code::RECHARGE_THIRD_LOG);

    }

    public function qrCode(RechargeOrder $rechargeOrder)
    {
        // TODO: Implement qrCode() method.
        $payurl = $this->getPostResUrl($rechargeOrder);
        $url = parse_url($payurl, PHP_URL_QUERY);
        parse_str($url, $output);
        if ( ! array_key_exists('url', $output)) {
            return new HrefRedirectAction($payurl);
        } else {
            $qrurl = $output['url'];
        }
        return new QrCodeAction($qrurl);
    }

    public function wapReq(RechargeOrder $rechargeOrder)
    {
        // TODO: Implement wapReq() method.
        $url = $this->getPostResUrl($rechargeOrder);
        return new HrefRedirectAction($url);
    }
}
